ingress控制器作用

ingress controller可以为kubernetes 集群外用户访问Kubernetes集群内部pod提供代理服务。

  • 提供全局访问代理
  • 访问流程: 用户-->ingress controller-->service-->pod

image-20250502153107584

image-20250502153114880

nginx ingress controller部署

curl -k https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml  -o deploy.yaml

kubectl apply -f deploy.yaml  #默认是nodeport方式将ingress暴露在外
kubectl get pods -n ingress-nginx

ingress-http案例

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx1               #自定义ingress名称
  namespace: test
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: www.nginx1.com                 # 自定义域名
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nginx-svc1
            port:
              number: 80


apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx             #自定义ingress名称
  namespace: test
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: www.nginx1.com                 # 自定义域名
    http:
      paths:
      - pathType: Prefix
        path: "/nginx1"
        backend:
          service:
            name: nginx-svc1
            port:
              number: 80
      - pathType: Prefix
        path: "/nginx2"
        backend:
          service:
            name: nginx-svc1
            port:
              number: 80

ingress-https案例

kubectl create secret tls nginx-tls-secret --cert=server.crt --key=server.key -n ingress-nginx


apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx             #自定义ingress名称
  namespace: test
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - www.nginx1.com                                                    # 域名
    secretName: nginx-tls-secret
  rules:
  - host: www.nginx1.com                 # 自定义域名
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nginx-svc1
            port:
              number: 80

Ingress透传真实IP

  • 访问流程的架构图如下:

image-20250512171950710

  • 外部nginx需要配置:
proxy_set_header Host $host;   #将客户端请求中的 Host 头(或当前访问的域名)原样转发给后端服务器。假设用户访问的是:http://www.testnginx.com,这个请求头中会带有:www.testnginx.com,我们ingress是通过域名转发的,所以这项必须配置,不然转发不到后端服务。

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   #X-Forwarded-For 是一个 HTTP 标准头,用于记录 请求经过的代理链路中的所有 IP 地址。用户 IP 是 203.0.113.10,Nginx 本身已有 X-Forwarded-For: 100.100.137.202,Nginx 添加后变成:X-Forwarded-For: 100.100.137.202, 203.0.113.10
  • ingress需要配置:
kubectl edit cm ingress-nginx-controller -n ingress-nginx
data:
  compute-full-forwarded-for: "true" 
  use-forwarded-headers: "true"




compute-full-forwarded-for: "true":
    设置这个参数对应的nginx真实配置:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    当 Ingress-NGINX 转发请求时,它会将自己的 IP 加入 X-Forwarded-For,构成完整链路。
    $proxy_add_x_forwarded_for 表示:原有的 X-Forwarded-For 值 + 当前请求的客户端地址。

use-forwarded-headers: "true":
    设置这个参数对应的nginx真实配置:
        real_ip_header X-Forwarded-For;
        set_real_ip_from 0.0.0.0/0;
        real_ip_recursive on;
   意思是:从 X-Forwarded-For 获取真实客户端 IP,且允许递归解析这个字段中的多个地址。这样Ingress-NGINX的remote_addr取X-Forwarded-For的第一个ip为真实ip地址。
  • Nginx-pod上配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  当 Ingress-NGINX 转发请求时,它会将自己的 IP 加入 X-Forwarded-For,构成完整链路。

    set_real_ip_from 0.0.0.0/0;  # 所信任的代理ip
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
  • 业务pod通过X-Forwarded-For获取真实IP。

  • 注意:网上有很多人都说需要配置ingress的svc(nodeport类型),这里做出解释:

ExternalTrafficPolicy=Local(针对 NodePort 或 LoadBalancer)和ExternalTrafficPolicy=Cluster 区别:

配置 是否保留客户端真实 IP 流量是否可以转发到其它节点 kube-proxy 行为 使用场景
Cluster(默认) ❌ 不保留(源 IP 被 NAT 成 Node IP) ✅ 是,转发到任何节点的 Pod 会将流量负载均衡到所有节点上的 Pod 标准服务可用性、流量分散
Local ✅ 保留客户端真实 IP ❌ 否,只转发到本节点上的 Pod 只会转发给本节点的 Pod,否则拒绝连接 想保留真实 IP、或结合负载均衡器使用

我这里ingress的svc(nodeport类型)设置的是ExternalTrafficPolicy=Cluster 还能获取到真实IP的原因是:

我的请求是经过“前置 Nginx ”转发过来的,externalTrafficPolicy: Local 是用于直接(重点:是直接访问)访问 NodePort 或 LoadBalancer 的情况

也就是说,客户端请求并不是直接打到 NodePort,而是先被一个 Nginx转发进来的,这些前置代理会添加或保留 X-Forwarded-For 头。

在外部 Nginx 加了:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

在 Ingress-NGINX 的 ConfigMap 设置了:

use-forwarded-headers: "true"
compute-full-forwarded-for: "true"

所以,虽然 Ingress Pod 看到的 remote_addr 是 kube-proxy 的节点 IP,但它通过 X-Forwarded-For 能取到真实客户端 IP

results matching ""

    No results matching ""